package com.cssy.xxkj.logic.service.impl;

import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSONArray;
import com.byd.acegiext.domain.User;
import com.cssy.xxkj.logic.contants.BillStatusUtil;
import com.cssy.xxkj.logic.contants.BillTypeConstant;
import com.cssy.xxkj.logic.dao.LogicProductionPlanDAO;
import com.cssy.xxkj.logic.dao.LogicProductionPlanItemDAO;
import com.cssy.xxkj.logic.dao.LogicProductionStorageinDAO;
import com.cssy.xxkj.logic.dao.LogicProductionStorageinItemDAO;
import com.cssy.xxkj.logic.dao.LogicSalesDAO;
import com.cssy.xxkj.logic.entity.LogicProductionPlanDO;
import com.cssy.xxkj.logic.entity.LogicProductionPlanItemDO;
import com.cssy.xxkj.logic.entity.LogicProductionStorageinDO;
import com.cssy.xxkj.logic.entity.LogicProductionStorageinItemDO;
import com.cssy.xxkj.logic.entity.LogicSalesDO;
import com.cssy.xxkj.logic.service.ILogicHsUtilService;
import com.cssy.xxkj.logic.service.ILogicProductionStorageInService;
import com.plat.exception.SyBaseException;
import com.plat.helper.SearchCondition;
import com.plat.helper.SearchConditions;
import com.plat.helper.SearchResult;
import com.plat.util.DateUtils;
import com.plat.util.GlobalResLoader;
import com.plat.util.IDCodeTypeUtil;
import com.plat.util.SessionUtil;
import com.yuendong.sy.po.code.SyCode;
import com.yuendong.sy.service.code.impl.SyCodeService;
@Service("logicProductionStorageInService")
public class LogicProductionStorageInServiceImpl implements ILogicProductionStorageInService{
	private static final Logger logger = Logger.getLogger(LogicProductionStorageInServiceImpl.class);
	@Resource(name = "logicProductionStorageinDAO")
	private LogicProductionStorageinDAO logicProductionStorageinDAO;
	@Resource(name = "logicProductionStorageinItemDAO")
	private LogicProductionStorageinItemDAO logicProductionStorageinItemDAO;
	@Resource(name = "syCodeService")
	private SyCodeService syCodeService;
	@Resource(name = "logicProductionPlanDAO")
	private LogicProductionPlanDAO logicProductionPlanDAO;
	@Resource(name = "logicProductionPlanItemDAO")
	private LogicProductionPlanItemDAO logicProductionPlanItemDAO;
	@Resource(name = "logicSalesDAO")
	private LogicSalesDAO logicSalesDAO;
	@Resource(name = "logicHsUtilService")
	private ILogicHsUtilService logicHsUtilService;
	@Override
	public SearchResult findListByExample(SearchConditions scs)
			throws SyBaseException {
		SearchResult rs=new SearchResult(scs);
		List<LogicProductionStorageinDO>  list= logicProductionStorageinDAO.find(scs);
		rs.setRecordCount(logicProductionStorageinDAO.count(scs));
		rs.setResults(list);
		return rs;
	}

	@Override
	public Integer delete(String id, User user) throws SyBaseException {
		LogicProductionStorageinDO basic = new LogicProductionStorageinDO();
		basic.setBizModifyDate(new Date());
		basic.setBizModifyName(user.getName());
		basic.setId(id);
		basic.setRemoved(1l);
		return logicProductionStorageinDAO.deleteBizRemoved(id);
	}

	@Override
	public Integer update(LogicProductionStorageinDO t, User user) throws SyBaseException {
		t.setBizModifyDate(new Date());
		t.setBizModifyName(user.getName());
		t.setBizVersionMark(t.getBizVersion());
		t.setBizVersion(t.getBizVersion()+1);
		return logicProductionStorageinDAO.updateLogicProductionStorageinDO(t);
	}

	@Override
	public LogicProductionStorageinDO save(LogicProductionStorageinDO t, User user)
			throws SyBaseException {
		Date date=new Date();
		t.setBizCreatorName(user.getName());
		t.setBizCreatorDate(date);
		t.setBizVersion(1);
		logicProductionStorageinDAO.insertLogicProductionStorageinDO(t);
		return t;
	}

	@Override
	public LogicProductionStorageinDO findListById(String id) throws SyBaseException {
		return logicProductionStorageinDAO.findLogicProductionStorageinDOByPrimaryKey(id);
	}

	@Override
	public void inSave(HttpServletRequest request,
			LogicProductionStorageinDO curAP)throws SyBaseException{
		try{
			String json = request.getParameter("addressInfos");
			List<LogicProductionStorageinItemDO> axxlist=JSONArray.parseArray(json, LogicProductionStorageinItemDO.class);
			if(curAP==null || StringUtils.isBlank(curAP.getId())){
				SearchConditions inScs = new SearchConditions();
				inScs.addCondition("zd002OriCode", curAP.getZd002OriCode(), SearchCondition.OP_EQUAL);
				inScs.addCondition("zd011BillStatus", BillStatusUtil.PROSTORIN_STATUS_ONE, SearchCondition.OP_EQUAL);
				Integer planCount = this.logicProductionStorageinDAO.count(inScs);
				if(planCount!=null &&planCount>0){
					throw new SyBaseException(curAP.getZd002OriCode()+"的计划单号存在未处理的单据");
				}
				//新增
				curAP.setZd001InCode(syCodeService.getCode(BillTypeConstant.PROIN,BillTypeConstant.PROIN,SyCode.DATE_YYMM,5));
				String id = IDCodeTypeUtil.getId();
				curAP.setId(id);
				String zd010OtherDate =request.getParameter("zd010OtherDate");
				curAP.setZd010OtherDate(DateUtils.stringToDate(zd010OtherDate));
				this.save(curAP, SessionUtil.getUser(request));
				for (LogicProductionStorageinItemDO lii : axxlist){
					lii.setId(IDCodeTypeUtil.getId());
					lii.setZd001OtherInId(id);
					logicProductionStorageinItemDAO.insertLogicProductionStorageinItemDO(lii);
				}
			}else{
				//修改
				if(BillStatusUtil.PROSTORIN_STATUS_FIVE.equals(curAP.getZd011BillStatus())){
					//修改库存
					int rt=0;
					rt=this.update(curAP, SessionUtil.getUser(request));
					if(0==rt){
						throw new SyBaseException("您修改的行数据发生改变！请重新打开查看");
					}
					LogicProductionStorageinDO loi = logicProductionStorageinDAO.findLogicProductionStorageinDOByPrimaryKey(curAP.getId());
					for (LogicProductionStorageinItemDO lii : axxlist){
						//修改库存
						this.logicHsUtilService.processProdStorageInItem(loi, lii, SessionUtil.getUser(request));
					}
					logger.info("更新仓库库存成功");
					
					//更新计划单的库存状态
					LogicProductionStorageinDO in = this.findListById(curAP.getId());
					LogicProductionPlanDO plan = new LogicProductionPlanDO();
					plan.setZd001FormCode(in.getZd002OriCode());
					List<LogicProductionPlanDO> planlist=logicProductionPlanDAO.findListByExample(plan);
					if(planlist!=null&&!planlist.isEmpty()&&planlist.size()>0){
						if(validateCompletPlan(in)){
							planlist.get(0).setZd012WareStatus(2l);
							//修改销售订单单据状态为生产完成
							SearchConditions saleScs = new SearchConditions();
							saleScs.addCondition("zd001FormCode", planlist.get(0).getZd002OriCode(), SearchCondition.OP_EQUAL);
							saleScs.addCondition("zd002PiCode", planlist.get(0).getZd003PiCode(), SearchCondition.OP_EQUAL);
							List<LogicSalesDO> saleList = logicSalesDAO.find(saleScs);
							if(saleList!=null&&!saleList.isEmpty()&&saleList.size()>0){
								LogicSalesDO sale = saleList.get(0);
								sale.setZd024Billstatus(BillStatusUtil.SES_STATUS_FIVE);
								sale.setBizVersionMark(sale.getBizVersion());
								sale.setBizVersion(sale.getBizVersion()+1);
								logicSalesDAO.updateLogicSalesDO(sale);
							}
						}else{
							planlist.get(0).setZd012WareStatus(1l);
						}
						planlist.get(0).setBizVersionMark(planlist.get(0).getBizVersion());
						planlist.get(0).setBizVersion(planlist.get(0).getBizVersion()+1);
						int r=logicProductionPlanDAO.updateLogicProductionPlanDO(planlist.get(0));
						if(r==0){
							throw new SyBaseException("您操作的原始单据数据发生了改变!请您重新打开编辑！");
						}
						logger.info("更新生产计划单仓库状态成功");
					}
				}else{
					String zd010OtherDate =request.getParameter("zd010OtherDate");
					curAP.setZd010OtherDate(DateUtils.stringToDate(zd010OtherDate));
					int rt=0;
					rt=this.update(curAP, SessionUtil.getUser(request));
					if(0==rt){
						throw new SyBaseException("您修改的行数据发生改变！请重新打开查看");
					}
					logicProductionStorageinItemDAO.deleteProById(curAP.getId());
					for (LogicProductionStorageinItemDO lii : axxlist){
						lii.setId(IDCodeTypeUtil.getId());
						lii.setZd001OtherInId(curAP.getId());
						logicProductionStorageinItemDAO.insertLogicProductionStorageinItemDO(lii);
					}
				}
			}
		}catch(Exception e){
			e.printStackTrace();
			logger.info("生产入库操作失败！");
			throw new SyBaseException(GlobalResLoader.getOpfailed() + e.getMessage());
		}
	}

	@Override
	public Integer deleteBizRemoved(String id) throws SyBaseException {
		return logicProductionStorageinDAO.deleteBizRemoved(id);
	}

	@Override
	public List<LogicProductionStorageinItemDO> findStorInItemList(String inId)
			throws SyBaseException {
		SearchConditions scs = new SearchConditions();
		scs.setRemovedProperty(null);
		if(scs.getOrderBy()==null){
			scs.setOrderBy("(zd020Order + 0 )");
		}
		scs.addCondition("zd001OtherInId", inId, SearchCondition.OP_EQUAL);
		List<LogicProductionStorageinItemDO>  list=logicProductionStorageinItemDAO.find(scs);
		return list;
	}
	
	@Override
	public Map<String, BigDecimal> findStorageinItemToMap(Map<String, Object> paramMap) 
			throws SyBaseException{
		List<LogicProductionStorageinItemDO> inItemList = logicProductionStorageinItemDAO.findListByMap(paramMap);
		if(inItemList==null||inItemList.isEmpty()||inItemList.size()==0){
			return null;
		}else{
			Map<String, BigDecimal> hasSgeinItemMap = new HashMap<String, BigDecimal>();
			for(LogicProductionStorageinItemDO inItem : inItemList){
				if(inItem==null||StringUtils.isBlank(inItem.getId())){
					continue;
				}
				String keyStr = paramMap.get("piCode") + "_"
						+ paramMap.get("oriCode") + "_"
						+ inItem.getZd002MaterialsCode() + "_"
						+ inItem.getZd015MaterialsSize() + "_"
						+ inItem.getZd004MaterialsModel() + "_"
						+ inItem.getZd017MaterialsQuality() + "_"
						+ inItem.getZd016MaterialsColor();
				BigDecimal outQuantity = inItem.getZd007Quantity()==null?BigDecimal.ZERO:inItem.getZd007Quantity();
				if(hasSgeinItemMap.get(keyStr)==null){
					hasSgeinItemMap.put(keyStr, outQuantity);
				}else{
					hasSgeinItemMap.put(keyStr, outQuantity.add(hasSgeinItemMap.get(keyStr)));
				}
			}
			return hasSgeinItemMap;
		}
	}
	
	/**
	 * 验证是否完全入库
	 * @param stogrageOut
	 * @return
	 */
	private boolean validateCompletPlan(LogicProductionStorageinDO stogrageIn){
		boolean completPlan = true;
		Map<String, Object> paramMap = new HashMap<String, Object>();
		paramMap.put("formCode", stogrageIn.getZd002OriCode());
		List<LogicProductionPlanItemDO> planItemList = logicProductionPlanItemDAO.findListByMap(paramMap);
		
		paramMap.clear();
		paramMap.put("piCode", stogrageIn.getZd003PiCode());
		paramMap.put("oriCode", stogrageIn.getZd002OriCode());
		paramMap.put("billSt", BillStatusUtil.PROSTORIN_STATUS_FIVE);
		Map<String, BigDecimal> hasQuantityMap = this.findStorageinItemToMap(paramMap);
		for(LogicProductionPlanItemDO planItem : planItemList){
			if(planItem==null||StringUtils.isBlank(planItem.getId())){
				continue;
			}
			String keyStr = paramMap.get("piCode") + "_"
				+ paramMap.get("oriCode") + "_"
				+ planItem.getZd007MaterialsCode() + "_"
				+ planItem.getZd038MaterialsSize() + "_"
				+ planItem.getZd010MaterialsModel() + "_"
				+ planItem.getZd042MaterialsQuality() + "_"
				+ planItem.getZd041MaterialsColor();
			BigDecimal hasQuantity = hasQuantityMap.get(keyStr);
			if(hasQuantity==null){
				hasQuantity = BigDecimal.ZERO;
			}
			BigDecimal saleQuantity = planItem.getZd013Quantity()==null?BigDecimal.ZERO:planItem.getZd013Quantity();
			int compUp = saleQuantity.subtract(hasQuantity).compareTo(BigDecimal.ZERO);
			if(compUp==1){
				completPlan = false;
			}
		}
		return completPlan;
	}
	
}
